We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

findFirstById() <- should we use bind here?

When using find() or findFirst() we use binding to prevent sql injections. Is this the same for findFirstById()? I tried using binding with it, but doesn't seem to work.



2.1k

findFirstById, i believe its the same as findFirst("id = smth").

to bind i believe its findFirst(["condition" => "id = ?1", "binds" = [1 => $id]]); or i think it is query->execute(["condition" => "id = ?1", "binds" = [1 => $id]]);



5.7k

al35mm, you could do it like this:

Users::findFirst([
    'conditions' => 'id = :id:',
    'bind' => [
        'id' => $id
    ],
    'bindTypes' => [
        'id' => \Phalcon\Db\Column::BIND_PARAM_INT
    ]
]);

bindTypes is used for a little extra security:

https://docs.phalcon.io/en/latest/reference/models.html#finding-records

"When binding parameters, you can use this parameter to define additional casting to the bound parameters increasing even more the security"



20.4k
edited Jan '15

Thanks for the answers. OK so just to confirm, using findFirstBy<field>() e.g. findFirstById() is virtually unusable for security reasons, unless you are passing in an internally generated (safe) value that is not derived from a user inputted value? Thus for the most part you are better off using findFirst() with binding?

I thought that maybe findFirstBy<field>() would have automatic binding based on the field type.



98.9k

This:

Users::findFirstById($id);

is the same as:

Users::findFirst([
    'conditions' => 'id = :id:',
    'bind' => [
        'id' => $id
    ],
    'bindTypes' => [
        'id' => \Phalcon\Db\Column::BIND_PARAM_INT
    ]
]);


5.7k
edited Jan '15

Honestly, I wasn't confident enough to answer whether or not it is escaped by default.

So here is what I did. I changed one of my queries and ran the query profiler.

The result is as follows:

// Issue the request
$client = Clients::findFirstByPublicKey($key);

// The profile result
SELECT `clients`.`public_key`, `clients`.`private_key`, `clients`.`status`, `clients`.`type` FROM `clients` WHERE `clients`.`public_key` = :0 LIMIT 1

It looks like the framework does indeed use prepared statements when using findFirstBy<propertyName>().

Result: Using findFirstBy<propertyName>($value) IS SECURE

Edit:: Thanks Phalcon - Was running my query profiler when you responded. Thanks again!



20.4k

Ak ok thanks Phalcon. That changes everything - findFirstById() is automatically bound. This should be added to the binding documentation!

Thanks also Steven.



2.1k

documentation is REALLY out of date, we need to update it =d